//
//  DownloadTask.m
//  DownloadManagerDemo
//
//  Created by ejiang on 2021/12/9.
//

#import "DownloadTask.h"

@implementation Speed

@end

@implementation FileInfo

@end

//@implementation DownloadError
//
//+ (instancetype)errorWithDomain:(NSString *)domain code:(NSInteger)code errorMessage:(nonnull NSString *)errorMessage {
//    DownloadError * error = [[DownloadError alloc] init];
//    error.domain = domain;
//    error.code = code;
//    error.errorMessage = errorMessage;
//    return error;
//}
//
//@end

@implementation DownloadTask

- (instancetype)initWithDownloadPath:(NSString *)downloadPath targetName:(NSString *)targetName targetDir:(NSString *)targetDir {
    self = [super init];
    if (self) {
        _taskId = [NSUUID UUID].UUIDString;
        _downloadPath = [downloadPath copy];
        _status = DownloadTaskStatusUnknown;
        _info = [[FileInfo alloc] init];
        _speed = [[Speed alloc] init];
        
        if (targetName == nil || [targetName length] == 0) {
            _targetName = [[[[_downloadPath componentsSeparatedByString:@"?"] firstObject] componentsSeparatedByString:@"/"] lastObject];
        }
        _targetDir = (targetDir == nil || [targetDir length] == 0) ? nil : targetDir;
        
        NSString * fileName = [_targetName copy];
        int index = 1;
        NSString * ext = [fileName pathExtension];
        NSString * originalName = [fileName stringByReplacingOccurrencesOfString:[@"." stringByAppendingString:ext] withString:@""];
        while ([self fileNameIsExist:fileName]) {
            index += 1;
            fileName = [originalName stringByAppendingFormat:@" %d.%@", index, ext];
        }
        if ([_targetName isEqualToString:fileName] == NO) {
            _targetName = fileName;
        }
    }
    return self;
}

- (BOOL)fileNameIsExist:(NSString *)fileName {
    NSString * rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    if ([_targetDir hasPrefix:@"/"]) {
        rootPath = [rootPath stringByAppendingString:_targetDir];
    } else {
        rootPath = [rootPath stringByAppendingPathComponent:_targetDir];
    }
    
    rootPath = [rootPath stringByAppendingPathComponent:fileName];
    
    BOOL isExist = NO;
    if ([[NSFileManager defaultManager] fileExistsAtPath:rootPath]) {
        // 重命名
        isExist = YES;
    } else {
        BOOL count = [DownloadTask rowCountWithWhere:[NSString stringWithFormat:@"targetName = '%@'", fileName]];
        if (count != 0) {
            // 重命名
            isExist = YES;
        }
    }
    return isExist;
}

- (BOOL)moveTmpToTarget:(NSURL *)tmpURL {
    self.status = DownloadTaskStatusMoving;
    NSString * rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    if (self.targetDir != nil) {
        if ([self.targetDir hasPrefix:@"/"]) {
            rootPath = [rootPath stringByAppendingString:self.targetDir];
        } else {
            rootPath = [rootPath stringByAppendingPathComponent:self.targetDir];
        }
    }
    BOOL isDir = NO;
    BOOL isExist = NO;
    if ([[NSFileManager defaultManager] fileExistsAtPath:rootPath isDirectory:&isDir]) {
        if (isDir == NO) {
            isExist = [[NSFileManager defaultManager] createDirectoryAtPath:rootPath withIntermediateDirectories:YES attributes:nil error:nil];
        } else {
            isExist = YES;
        }
    } else {
        isExist = [[NSFileManager defaultManager] createDirectoryAtPath:rootPath withIntermediateDirectories:YES attributes:nil error:nil];
    }
    if (isExist == NO) {
        self.errorDic = @{
            @"Domain" : kFileHandleError,
            @"Code" : @(FileHandleErrorTargetNotExist),
            @"Message" : @"文件夹不存在并且创建失败"
        };
        return NO;
    }
    
    rootPath = [rootPath stringByAppendingPathComponent:self.targetName];
    
    NSError * error;
    BOOL result = [[NSFileManager defaultManager] moveItemAtURL:tmpURL toURL:[NSURL fileURLWithPath:rootPath] error:&error];
    if (error) {
        self.errorDic = @{
            @"Domain" : kFileHandleError,
            @"Code" : @(FileHandleErrorMoveFail),
            @"Message" : @"目标文件夹已经存在同名文件"
        };
        return NO;
    }
    if (result == NO) {
        self.errorDic = @{
            @"Domain" : kFileHandleError,
            @"Code" : @(FileHandleErrorMoveFail),
            @"Message" : @"移动到目标文件夹失败"
        };
        return NO;
    }
    return YES;
}

- (void)saveTmpResumeData:(NSData *)resumeData {
    if (resumeData == nil || [resumeData length] == 0) {
        return;
    }
    NSString * ext = [self.targetName pathExtension];
    NSString * originalName = [self.targetName stringByReplacingOccurrencesOfString:[@"." stringByAppendingString:ext] withString:@""];
    NSString * tmpRootPath = NSTemporaryDirectory();
    NSString * tmpPath = [tmpRootPath stringByAppendingPathComponent:[originalName stringByAppendingString:@".tmp"]];
    
    [resumeData writeToFile:tmpPath atomically:YES];
}

- (NSData *)tmpResumeData {
    NSString * ext = [self.targetName pathExtension];
    NSString * originalName = [self.targetName stringByReplacingOccurrencesOfString:[@"." stringByAppendingString:ext] withString:@""];
    NSString * tmpRootPath = NSTemporaryDirectory();
    NSString * tmpPath = [tmpRootPath stringByAppendingPathComponent:[originalName stringByAppendingString:@".tmp"]];
    if ([[NSFileManager defaultManager] fileExistsAtPath:tmpPath] == NO) {
        return nil;
    }
    return [NSData dataWithContentsOfFile:tmpPath];
}

- (void)reInit {
    
    [self _removeLocal];
    
    self.speed = [[Speed alloc] init];
    self.errorDic = nil;
    self.info = [[FileInfo alloc] init];
    self.status = DownloadTaskStatusUnknown;
    [self updateToDB];
}

- (void)removeLocal {
    [self _removeLocal];
}

- (void)_removeLocal {
    NSString * rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    if (self.targetDir != nil) {
        if ([self.targetDir hasPrefix:@"/"]) {
            rootPath = [rootPath stringByAppendingString:self.targetDir];
        } else {
            rootPath = [rootPath stringByAppendingPathComponent:self.targetDir];
        }
    }
    rootPath = [rootPath stringByAppendingPathComponent:self.targetName];
    
    if ([[NSFileManager defaultManager] fileExistsAtPath:rootPath]) {
        [[NSFileManager defaultManager] removeItemAtPath:rootPath error:nil];
    }
}

+ (NSString *)getTableName {
    return @"DownloadTasks";
}

+ (NSString *)getPrimaryKey {
    return @"taskId";
}

- (void)setErrorDic:(NSDictionary *)errorDic {
    _errorDic = errorDic;
    if (errorDic) {
        self.status = DownloadTaskStatusError;
    }
}

@end
